package com.foreverwin.mes.production.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.foreverwin.mes.common.constants.HandleBOConstants;
import com.foreverwin.mes.core.exception.BusinessException;
import com.foreverwin.mes.core.utils.StringUtils;
import com.foreverwin.mes.meapi.model.Certification;
import com.foreverwin.mes.meapi.model.Resrce;
import com.foreverwin.mes.meapi.service.UserCertService;
import com.foreverwin.mes.production.mapper.ClockLogMapper;
import com.foreverwin.mes.production.model.ClockLog;
import com.foreverwin.mes.production.model.Station;
import com.foreverwin.mes.production.model.StationResource;
import com.foreverwin.mes.production.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zero123
 * @since 2019-01-03
 */
@Service
@Transactional(rollbackFor=Exception.class)
public class ClockLogServiceImpl extends ServiceImpl<ClockLogMapper, ClockLog> implements ClockLogService {

    @Autowired
    private ClockLogMapper clockLogMapper;
    @Autowired
    private StationService stationService;
    @Autowired
    private UserCertService userCertService;
    @Autowired
    private StationResourceService stationResourceService;
    @Autowired
    private WorkCenterShiftService workCenterShiftService;
    @Autowired
    private StationCertificationService stationCertificationService;

    @Override
    public ClockLog findLastEmployeeInResource(String site, String resource) {

        List<ClockLog> clockLogList = clockLogMapper.findLastEmployeeInResource(site, resource);
        if(clockLogList == null || clockLogList.size() <= 0) return null;

        return clockLogList.get(0);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<ClockLog> getResourceClockInEmployee(String site, String resource){

        //查询设备维护当前可用班次
        Map<String ,Object> map;

        try {
            map = workCenterShiftService.getCurrentShiftOfResource(site, resource, new Date());

            if(map == null){
                return null;
            }
            String shift = (String) map.get("shift");
            Date beginDateTime = (Date) map.get("beginTime");
            Date endDateTime = (Date) map.get("endTime");

            //ClockLog
            ClockLog queryModel = new ClockLog();
            queryModel.setSite(site);
            queryModel.setResrce(resource);
            queryModel.setShift(shift);
            queryModel.setBeginDateTime(beginDateTime);
            queryModel.setEndDateTime(endDateTime);

            return clockLogMapper.selectClockInEmployeeByResource(queryModel);

        } catch (BusinessException e) {
            return null;
        }
    }

    @Override
    public List<ClockLog> getStationClockInEmployee(String site, String station, Date nowDate) throws BusinessException { ;

        //查询班次
        Map<String,Object> map = getCurrentEffectiveShiftByStation(site, station, nowDate);
        if( map == null ){
            throw BusinessException.build("岗位【" + station  +"】不能匹配当前可用班次！");
        }
        String shift = (String) map.get("shift") ;
        Date beginDateTime = (Date) map.get("beginTime");
        Date endDateTime = (Date) map.get("endTime");

        //查询班次区间岗位打卡人员
        ClockLog queryModel = new ClockLog();
        queryModel.setSite(site);
        queryModel.setStation(station);
        queryModel.setShift(shift);
        queryModel.setBeginDateTime(beginDateTime);
        queryModel.setEndDateTime(endDateTime);

        return clockLogMapper.selectClockInEmployee(queryModel);
    }

    @Override
    public void clockIn(String site, String station, String employee, Date nowDate) throws BusinessException {

        //now Date
        //Date nowDate = new Date();
        String userBo = StringUtils.genHandle(HandleBOConstants.USER_BO,site,employee);

        //查询岗位信息
        Station stationInfo = stationService.getStation(site,station);
        if( stationInfo == null  ){
            throw BusinessException.build("岗位【" + station+"】不存在");
        }
        String stationBo = stationInfo.getHandle();

        //查询班次
        Map<String,Object> map = getCurrentEffectiveShiftByStation(site, station, nowDate);
        if( map == null ){
            throw BusinessException.build( "岗位【" + station  +"】当前无可用班次！");
        }
        String shift = (String) map.get("shift");
        String isAppointment = (String) map.get("isAppointment");
        Date beginDateTime = (Date) map.get("beginTime");
        Date endDateTime = (Date) map.get("endTime");

        //人员校验
        List<Certification> stationCertList = stationCertificationService.getCertificationList(stationBo);
        if(stationCertList != null && stationCertList.size() > 0){
            List<String> stationCertHandleList = stationCertList.stream().map(Certification::getHandle).collect(Collectors.toList());
            //查询用户证明
            List<Certification> userCertList = userCertService.getCertByUserBo(userBo);
            if(userCertList == null || userCertList.size() <= 0){
                throw BusinessException.build("人员【" +employee+"】没有分配证明");
            }
            List<String> userCertHandleList = userCertList.stream().map(Certification::getHandle).collect(Collectors.toList());
            boolean flag = userCertHandleList.containsAll(stationCertHandleList);
            if(!flag) {
                throw BusinessException.build("人员【" +employee+"】已分配证明不匹当前岗位");
            }
        }

        //当前岗位 班次是否已有人员上岗
        ClockLog queryModel = new ClockLog();
        queryModel.setSite(site);
        queryModel.setStation(station);
        queryModel.setShift(shift);
        queryModel.setStatus("Y");
        queryModel = clockLogMapper.selectOne(queryModel);
        if( queryModel!= null ){

            //状态变更
            ClockLog modifyModel = new ClockLog();
            modifyModel.setHandle(queryModel.getHandle());
            modifyModel.setStatus("N");
            modifyModel.setModifiedDateTime(nowDate);

            //替岗
            if("Y".equals(queryModel.getIsAppointment())){

                if(nowDate.getTime()-queryModel.getEndDateTime().getTime() < 0) {
                    if (employee.equals(queryModel.getEmployee())) {
                        throw BusinessException.build("用户【" + employee + "】在当前班次已经上岗");
                    }
                    modifyModel.setEndDateTime(queryModel.getBeginDateTime());
                    modifyModel.setElapsedTime("0");
                }
            }else{

                if(nowDate.getTime()-queryModel.getEndDateTime().getTime() < 0) {
                    if (employee.equals(queryModel.getEmployee())) {
                        throw BusinessException.build("用户【" + employee + "】在当前班次已经上岗");
                    }
                    modifyModel.setEndDateTime(nowDate);
                    long elapsedTime = (nowDate.getTime() - queryModel.getBeginDateTime().getTime()) / (1000 * 60);
                    modifyModel.setElapsedTime(elapsedTime + "");
                }

            }
            clockLogMapper.updateById(modifyModel);
        }

        //上岗
        ClockLog addModel = new ClockLog();
        addModel.setHandle("ClockLogBO:" + site + "," + station + "," + employee + "," + UUID.randomUUID());
        addModel.setSite(site);
        addModel.setStation(station);
        addModel.setShift(shift);
        addModel.setEmployee(employee);
        addModel.setIsAppointment(isAppointment);
        long elapsedTime = 0;
        if( "Y" == isAppointment ){
            addModel.setAppointmentTime(nowDate);
            addModel.setBeginDateTime(beginDateTime);
            elapsedTime = (endDateTime.getTime()-beginDateTime.getTime())/(1000*60);
        } else{
            addModel.setBeginDateTime(nowDate);
            elapsedTime = (endDateTime.getTime()-nowDate.getTime())/(1000*60);
        }
        addModel.setStatus("Y");
        addModel.setEndDateTime(endDateTime);
        addModel.setElapsedTime(elapsedTime+"" );
        addModel.setCreatedDateTime(nowDate);
        addModel.setModifiedDateTime(nowDate);

        clockLogMapper.insert(addModel);
    }

    @Override
    public void clockOut(String site, String station, String shift, String employee) throws BusinessException {

        //now Date
        Date nowDate = new Date();

        //queryModel
        ClockLog queryModel = new ClockLog();
        queryModel.setSite(site);
        queryModel.setStation(station);
        queryModel.setShift(shift);
        queryModel.setEmployee(employee);
        queryModel.setStatus("Y");
        queryModel = clockLogMapper.selectOne(queryModel);
        if(queryModel == null){
            throw BusinessException.build("人员【" + employee+"】已经离岗");
        }else{

            Date endDateTime = queryModel.getEndDateTime();
            if(nowDate.getTime()-endDateTime.getTime() >= 0){
                throw BusinessException.build("人员【" + employee+"】已经离岗");
            }else{

                //离岗
                ClockLog modifyModel = new ClockLog();
                modifyModel.setHandle(queryModel.getHandle());
                modifyModel.setStatus("N");
                modifyModel.setEndDateTime(nowDate);
                modifyModel.setModifiedDateTime(nowDate);
                long elapsedTime = (nowDate.getTime()-queryModel.getBeginDateTime().getTime())/(1000*60);
                modifyModel.setElapsedTime(elapsedTime+"");

                clockLogMapper.updateById(modifyModel);
            }
        }
    }

    @Override
    public void verifyClockIn(String site, String resource, Date nowDate) throws BusinessException {
        //查询设备维护当前可用班次
        Map<String ,Object> map = workCenterShiftService.getCurrentShiftOfResource(site, resource, nowDate);
        if(map == null){
            throw BusinessException.build("设备所属工作中心未维护可用班次");
        }
        String shift = (String) map.get("shift");
        Date beginTime = (Date) map.get("beginTime");
        Date endTime = (Date) map.get("endTime");
        //查询设备所属岗位
        List<StationResource> stationList = stationResourceService.getStationListByResource(site ,resource);
        if(stationList == null || stationList.size() <= 0){
            throw BusinessException.build("设备没有维护所属岗位");
        }
        for(StationResource stationResource: stationList){
            String station = stationResource.getStation();
            //查询岗位人员
            ClockLog queryModel = new ClockLog();
            queryModel.setSite(site);
            queryModel.setStation(station);
            queryModel.setShift(shift);
            queryModel.setBeginDateTime(beginTime);
            queryModel.setEndDateTime(endTime);
            List<ClockLog> clockList = clockLogMapper.selectClockInEmployee(queryModel);
            if(clockList == null || clockList.size() <=0){
                throw BusinessException.build("人员未上岗，不能进行生产");
            }
        }
    }

    @Override
    public void verifySpotCheck(String site, String resource, Date nowDate) throws BusinessException {
        //查询设备维护当前可用班次
        Map<String ,Object> map = workCenterShiftService.getCurrentShiftOfResource(site, resource, nowDate);
        if(map == null){
            throw BusinessException.build("设备所属工作中心没有维护可用班次");
        }
        /*
        String shift = (String) map.get("shift");
        Date beginTime = (Date) map.get("beginTime");
        Date endTime = (Date) map.get("endTime");
        //查找机型
        String resourceBo = StringUtils.genHandle(HandleBOConstants.RESOURCE_BO, site, resource);
        CustomFields customFields = resourceService.getEqTypeResource(resourceBo);
        if(customFields == null){
            throw BusinessException.build("设备没有维护机型");
        }
        String equipType = customFields.getValue();
        //查询开班点检设定
        Wrapper wrapper = new EntityWrapper();
        wrapper.eq("SITE", site);
        wrapper.eq("EQUIP_TYPE", equipType);
        wrapper.eq("USER_SHIFT", shift);
        wrapper.eq("STATUS", "Y");
        List<SpotInspection> spotList = spotInspectionService.selectList(wrapper);
;       if(spotList != null && spotList.size() > 0) {
            SpotInspection spotInspection = spotList.get(0);
            //开班点检确认
            SpotInspectionTask taskModel = spotInspectionTaskService.getLastSpotTaskOfShift(site, resource, shift, beginTime, endTime);
            if (taskModel != null) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(beginTime);
                if (spotInspection != null && StringUtils.notBlank(spotInspection.getToleranceTime())) {
                    calendar.add(Calendar.MINUTE, Integer.parseInt(spotInspection.getToleranceTime()));
                }
                if ((calendar.getTime().getTime() - nowDate.getTime()) < 0) {
                    //超过容差时间
                    if (!DataValueConstant.TASK_STATUS_COMPLETE.equals(taskModel.getStatus())) {
                        throw BusinessException.build("设备开班点检任务没有完成");
                    } else if (!DataValueConstant.TASK_RESULT_OK.equals(taskModel.getResult())) {
                        throw BusinessException.build("设备的开班点检检验不通过");
                    }
                } else {
                    //在容差时间内
                    if (!DataValueConstant.TASK_STATUS_NEW.equals(taskModel.getStatus()) && !DataValueConstant.TASK_RESULT_OK.equals(taskModel.getResult())) {
                        throw BusinessException.build("设备的开班点检检验不通过");
                    }
                }
            } else {
                throw BusinessException.build("设备当前班次没有创建开班点检任务");
            }
        }*/
    }


    /**
     * 根据岗位查询当前有效的班次
     * @param site
     * @param station
     * @return
     */
    public Map<String,Object> getCurrentEffectiveShiftByStation(String site, String station, Date nowDate) throws BusinessException {

        //查询岗位信息
        Station stationInfo = stationService.getStation(site,station);
        if( stationInfo == null  ){
            throw BusinessException.build("岗位【" + station+"】不存在");
        }
        String stationBo = stationInfo.getHandle();
        //岗位状态
        if( !"Y".equals(stationInfo.getStatus())){
            throw BusinessException.build("岗位【" +station+ "】状态不可用");
        }

        //查询岗位分配的设备
        List<Resrce> resourceList = stationResourceService.getResourceList(stationBo);
        if( resourceList == null || resourceList.size() < 1 ){
            throw BusinessException.build("当前岗位【" + station + "】没有分配可用设备");
        }
        String resource = resourceList.get(0).getResrce();

        //查询当前工作中心维护班次
        return workCenterShiftService.getAppointOrCurrentShiftOfResource(site, resource, nowDate);
    }
}